home *** CD-ROM | disk | FTP | other *** search
/ MIDICraft's MIDINET CD-ROM / MIDICraft's MIDINET CD-ROM.iso / DOSUTILS / TXT2MIDI.ZIP / MIDILEX.L < prev    next >
Encoding:
Lex Description  |  1996-12-29  |  13.2 KB  |  629 lines

  1. %{
  2. #include "txt2midi.h"
  3. #include "midiread.hpp"
  4. #include "math.h"
  5. #include <string.h>
  6. #include <ctype.h>
  7. #include <assert.h>
  8.  
  9. #ifdef __MSDOS__
  10. #define STRICMP stricmp
  11. #else
  12. #define STRICMP strcmp
  13. #endif
  14.  
  15. extern int yyerror( char* msg );
  16.  
  17. struct lexstate
  18. {
  19.   int index; // file
  20.   long linenr;
  21.   YY_BUFFER_STATE buffer;
  22.  
  23.   lexstate* save;
  24. };
  25.  
  26. void init_lexstate(lexstate* l)
  27. {
  28.   assert(l != 0);
  29.   l->index = 0;
  30.   l->linenr = 1;
  31.   l->buffer = 0;
  32.   l->save = 0;
  33. }
  34.  
  35. lexstate *src = 0;
  36.  
  37. #define MAXNAMES  10
  38. char filename[MAXNAMES][128];
  39. int filenames = 0;
  40.  
  41. int noteval(char* s);
  42. void includefile(char* name);
  43.  
  44. #undef YY_DECL
  45. #define YY_DECL int ylex(void)
  46.  
  47. %}
  48.  
  49. hexdigit        [a-fA-F0-9]
  50. decdigit    [0-9]
  51. ws        [ \t]
  52. sign        [+-]
  53. char            (\\[Xx]{hexdigit}{hexdigit}|\\.|.)
  54. float        {decdigit}+("."{decdigit}+)?
  55. eow        [^a-zA-Z0-9_]
  56.  
  57. %start MIDI CMNT PROGRAM
  58.  
  59. %%
  60.  
  61.  if ( yy_start == 0 ) BEGIN MIDI;
  62.  
  63. <MIDI>\"{char}*\"    {
  64.              char* s = (char*)yytext+1, *t;
  65.  
  66.           t = (char*)yytext;
  67.           yyleng = 0;
  68.           while (*s != '"')
  69.           {
  70.             if (*s == '\\')
  71.             {
  72.               s++;
  73.               if (*s == 'x' || *s == 'X')
  74.               {
  75.               int val = 0;
  76.  
  77.             s++;
  78.             if (isdigit(*s))
  79.               val = *s - '0';
  80.             else
  81.               val = toupper(*s) - 'A'+10;
  82.             s++;
  83.             if (isdigit(*s))
  84.               val = val * 16 + (*s - '0');
  85.             else
  86.               val = val * 16 + (toupper(*s) - 'A'+10);
  87.             s++;
  88.             *t++ = val;
  89.               }
  90.               else
  91.               {
  92.             *t++ = *s++;
  93.               }
  94.             }
  95.             else
  96.               *t++ = *s++;
  97.             yyleng++;
  98.           }
  99.           *t = 0;
  100.           return(_TEXT);
  101.         }
  102.  
  103. <MIDI>"#"{ws}*include{ws}+"<".+">".*$  {
  104.             char* s = strchr((char*)yytext, '<');
  105.  
  106.             if (s)
  107.               strcpy((char*)yytext, s+1);
  108.             s = strchr((char*)yytext, '>');
  109.             if (s)
  110.               *s = 0;
  111.             includefile((char*)yytext);
  112.             }
  113.  
  114.  
  115. <MIDI>\/\/.*$    ;    /* comment */
  116.  
  117. <MIDI>[ \t]        ;    /* blanks */
  118.  
  119. <MIDI>\n        src->linenr++;
  120.  
  121. <MIDI>[CDFGAcdfga]("#"|"is")?"-"?1?[0-9]?  |
  122. <MIDI>[BHDEGbhdeg]("b"|"es")?"-"?1?[0-9]? |
  123. <MIDI>[AaEe]s?"-"?1?[0-9] |
  124. <MIDI>[BbHh]"-"?1?[0-9] {
  125.      yylval.longv = noteval((char*)yytext);
  126.      return(_NOTE);
  127.    }
  128.  
  129. <MIDI>{sign}?"$"{hexdigit}+   {
  130.             if (yytext[0] == '-' || yytext[0] == '+')
  131.             {
  132.               yylval.longv = strtol(strchr((char*)yytext, '$')+1, 0, 16);
  133.               if (yytext[0] == '-')
  134.                 yylval.longv = -yylval.longv;
  135.               return(_SIGNEDNUMBER);
  136.             }
  137.             else
  138.             {
  139.               yylval.longv = strtol(strchr((char*)yytext, '$')+1, 0, 16);
  140.               return(_NUMBER);
  141.             }
  142.               }
  143.  
  144. <MIDI>{sign}?"0[xX]"{hexdigit}+   {
  145.             yylval.longv = strtol((char*)yytext+2, 0, 16);
  146.             return(_NUMBER);
  147.             if (yytext[0] == '-' || yytext[0] == '+')
  148.             {
  149.               yylval.longv = -strtol(strchr((char*)yytext, '0'), 0, 16);
  150.               return(_SIGNEDNUMBER);
  151.             }
  152.             else
  153.             {
  154.               yylval.longv = strtol(strchr((char*)yytext, '0'), 0, 16);
  155.               return(_NUMBER);
  156.             }
  157.               }
  158.  
  159. <MIDI>{sign}?0[0-7]*          {
  160.             if (yytext[0] == '-' || yytext[0] == '+')
  161.             {
  162.               yylval.longv = -strtol(strchr((char*)yytext, '0'), 0, 8);
  163.               return(_SIGNEDNUMBER);
  164.             }
  165.             else
  166.             {
  167.               yylval.longv = strtol(strchr((char*)yytext, '0'), 0, 8);
  168.               return(_NUMBER);
  169.             }
  170.               }
  171.  
  172. <MIDI>{sign}?[0-9]+          {
  173.             if (yytext[0] == '-' || yytext[0] == '+')
  174.             {
  175.               yylval.longv = strtol((char*)yytext, 0, 10);
  176.               return(_SIGNEDNUMBER);
  177.             }
  178.             else
  179.             {
  180.               yylval.longv = strtol((char*)yytext, 0, 10);
  181.               return(_NUMBER);
  182.             }
  183.               }
  184.  
  185. <MIDI>"*"|"x"                     return(_TIMES);
  186.  
  187. <MIDI>"/"                      return(_DIV);
  188.  
  189. <MIDI>";"                      return(_SEP);
  190.  
  191. <MIDI>"."              return(_ENDTACT);
  192.  
  193. <MIDI>"("              return('(');
  194.  
  195. <MIDI>")"              return(')');
  196.  
  197. <MIDI>":"              return(':');
  198.  
  199. <MIDI>"["              return('[');
  200.  
  201. <MIDI>"]"              return(']');
  202.  
  203. <MIDI>[Mm][Tt]hd          return(_HEAD);
  204.  
  205. <MIDI>[Mm][Tt]rk          return(_TRACK);
  206.  
  207. <MIDI>[Tt]empo              return(_TEMPO);
  208.  
  209. <MIDI>[Bb]eats{ws}+{float}      {
  210.                   char* s = (char*)yytext + 5;
  211.  
  212.                      yylval.floatv = atof(s);
  213.                      return(_BEATS);
  214.                   }
  215.  
  216. <MIDI>[Uu]nits?/{eow}          return(_UNIT);
  217.  
  218. <MIDI>[Ee][Nn][Dd]/{eow}          return(_END);
  219.  
  220. <MIDI>[Ss]eq[Nn]umber/{eow}      return(_SEQNUMBER);
  221.  
  222. <MIDI>[Tt]ext/{eow}          return(_GENERAL_TEXT);
  223.  
  224. <MIDI>[Cc]opyright/{eow}      return(_COPYRIGHT);
  225.  
  226. <MIDI>[Tt]rackname/{eow}      return(_TRACKNAME);
  227.  
  228. <MIDI>[Ii]nstrument/{eow}      return(_INSTRUMENT);
  229.  
  230. <MIDI>[Ll]yric/{eow}          return(_LYRIC);
  231.  
  232. <MIDI>[Mm]arker/{eow}          return(_MARKER);
  233.  
  234. <MIDI>[Kk]ey/{eow}          return(_KEY);
  235.  
  236. <MIDI>[Cc]ue[Pp]oint/{eow}      return(_CUEPOINT);
  237.  
  238. <MIDI>[Pp]refix[Cc]hannel/{eow}      return(_PREFIXCHANNEL);
  239.  
  240. <MIDI>[Pp]refix[Pp]ort/{eow}      return(_PREFIXPORT);
  241.  
  242. <MIDI>[Ss][Mm][Pp][Tt][Ee][Oo]fs/{eow}  return(_SMPTEOFS);
  243.  
  244. <MIDI>[Tt]act/{eow}          return(_TACT);
  245.  
  246. <MIDI>[Ee]vent/{eow}          return(_EVENT);
  247.  
  248. <MIDI>[Mm]eta[Ee]vent/{eow}      return(_METAEVENT);
  249.  
  250. <MIDI>[Ss]ys[Ee]vent/{eow}      return(_SYSEVENT);
  251.  
  252. <MIDI>[Pp]rogram/{eow}          { BEGIN PROGRAM; return(_PROGRAM); }
  253.  
  254. <MIDI>[Vv]ersion/{eow}          return(_VERSION);
  255.  
  256. <MIDI>[Cc]ontrol/{eow}          return(_CONTROL);
  257.  
  258. <MIDI>[Vv]elocy?on/{eow}      return(_VELOCON);
  259.  
  260. <MIDI>[Vv]elocy?off/{eow}      return(_VELOCOFF);
  261.  
  262. <MIDI>[Tt]ranspose/{eow}      return(_TRANSPOSE);
  263.  
  264. <MIDI>[Oo]n/{eow}          return(_ON);
  265.  
  266. <MIDI>[Oo]ff/{eow}          return(_OFF);
  267.  
  268. <MIDI>[Hh]bank/{eow}          return(_HBANK);
  269.  
  270. <MIDI>[Ll]bank/{eow}          return(_LBANK);
  271.  
  272. <MIDI>[Bb]ank[Aa]/{eow}          return(_BANKA);
  273.  
  274. <MIDI>[Bb]ank[Bb]/{eow}          return(_BANKB);
  275.  
  276. <MIDI>[Bb]ank[Cc]/{eow}          return(_BANKC);
  277.  
  278. <MIDI>[Bb]ank[Dd]/{eow}          return(_BANKD);
  279.  
  280. <MIDI>[Bb]ank[Dd]rums?/{eow}      return(_BANKDRUMS);
  281.  
  282. <MIDI>"+"              return(_NOTEON);
  283.  
  284. <MIDI>"-"              return(_NOTEOFF);
  285.  
  286. <MIDI>[Ll]oop/{eow}          return(_LOOP);
  287.  
  288. <MIDI>[Mm]ute/{eow}          return(_MUTE);
  289.  
  290. <MIDI>[Ss]olo/{eow}          return(_SOLO);
  291.  
  292. <MIDI>[Pp]art/{eow}          return(_PART);
  293.  
  294. <MIDI>[Cc]opy/{eow}          return(_COPY);
  295.  
  296. <MIDI>[Pp]rint/{eow}          return(_PRINT);
  297.  
  298. <MIDI>[Bb]alance/{eow}          return(_BALANCE);
  299.  
  300. <MIDI>[Hh]old/{eow}          return(_HOLD);
  301.  
  302. <MIDI>[Rr]everb/{eow}          return(_REVERB);
  303.  
  304. <MIDI>[Cc]horus/{eow}          return(_CHORUS);
  305.  
  306. <MIDI>[Bb]rightness/{eow}      return(_BRIGHTNESS);
  307.  
  308. <MIDI>[Ee]xpression/{eow}      return(_EXPRESSION);
  309.  
  310. <MIDI>[Pp]itchmodulation/{eow}      return(_PITCHMODULATION);
  311.  
  312. <MIDI>[Ll]eft/{eow}          return(_LEFT);
  313.  
  314. <MIDI>[Rr]ight/{eow}          return(_RIGHT);
  315.  
  316. <MIDI>[Ww]heel/{eow}          { yylval.bytev = 1; return(_CHANGE); }
  317.  
  318. <MIDI>[Bb]reath/{eow}          { yylval.bytev = 2; return(_CHANGE); }
  319.  
  320. <MIDI>[Ff]oot/{eow}          { yylval.bytev = 4; return(_CHANGE); }
  321.  
  322. <MIDI>[Pp]ortamento[Tt]ime/{eow}  { yylval.bytev = 5; return(_CHANGE); }
  323.  
  324. <MIDI>[Pp]ortamento/{eow}      { yylval.bytev = 65; return(_CHANGE); }
  325.  
  326. <MIDI>[Dd]ata/{eow}          { yylval.bytev = 6; return(_CHANGE); }
  327.  
  328. <MIDI>[Vv]olume/{eow}          { yylval.bytev = 7; return(_CHANGE); }
  329.  
  330. <MIDI>[Ss]ustain/{eow}          { yylval.bytev = 64; return(_CHANGE); }
  331.  
  332. <MIDI>[Ss]ostenuto/{eow}      { yylval.bytev = 66; return(_CHANGE); }
  333.  
  334. <MIDI>[Ss]oft[Pp]edal/{eow}      { yylval.bytev = 67; return(_CHANGE); }
  335.  
  336. <MIDI>[Dd]ata[Ii]nc/{eow}      { yylval.bytev = 68; return(_CHANGE); }
  337.  
  338. <MIDI>[Dd]ata[Dd]ec/{eow}      { yylval.bytev = 69; return(_CHANGE); }
  339.  
  340. <MIDI>[Ll]ow[rR][pP][nN]/{eow}      { yylval.bytev = 100; return(_CHANGE); }
  341.  
  342. <MIDI>[Hh]igh[rR][pP][nN]/{eow}      { yylval.bytev = 101; return(_CHANGE); }
  343.  
  344. <MIDI>[Pp]itch[Bb]end[Rr]ange/{eow}   { return(_PITCHBENDRANGE); }
  345.  
  346. <MIDI>[Ll]ocal[Oo]n/{eow}      { yylval.longv = 122l + (127l << 8); return(_MODE); }
  347.  
  348. <MIDI>[Ll]ocal[Oo]ff/{eow}      { yylval.longv = 122; return(_MODE); }
  349.  
  350. <MIDI>[Ss]ilent/{eow}          { yylval.longv = 123; return(_MODE); }
  351.  
  352. <MIDI>[Aa]ll[Nn]otes[Oo]ff/{eow}  { yylval.longv = 123; return(_MODE); }
  353.  
  354. <MIDI>[Oo]mni[Oo]ff/{eow}      { yylval.longv = 124; return(_MODE); }
  355.  
  356. <MIDI>[Oo]mni[Oo]n/{eow}      { yylval.longv = 125; return(_MODE); }
  357.  
  358. <MIDI>[Mm]ono[Oo]n/{eow}      { yylval.longv = 126; return(_MODE); }
  359.  
  360. <MIDI>[Pp]oly[Oo]n/{eow}      { yylval.longv = 127; return(_MODE); }
  361.  
  362. <MIDI>[Ss]ong[Pp]osition/{eow}      return(_SONGPOS);
  363.  
  364. <MIDI>[Ss]ong[Pp]os/{eow}      return(_SONGPOS);
  365.  
  366. <MIDI>[Ss]ong[Ss]elect/{eow}      return(_SONGSELECT);
  367.  
  368. <MIDI>[Tt]une[Rr]equest/{eow}      { yylval.bytev = 246; return(_COMMON); }
  369.  
  370. <MIDI>[Tt]iming[Cc]lock/{eow}      { yylval.bytev = 248; return(_COMMON); }
  371.  
  372. <MIDI>[Ss]tart/{eow}          { yylval.bytev = 250; return(_COMMON); }
  373.  
  374. <MIDI>[Cc]ontinue/{eow}          { yylval.bytev = 251; return(_COMMON); }
  375.  
  376. <MIDI>[Ss]top/{eow}          { yylval.bytev = 252; return(_COMMON); }
  377.  
  378. <MIDI>[Aa]ctive[Ss]ensing/{eow}      { yylval.bytev = 254; return(_COMMON); }
  379.  
  380. <MIDI>[Pp]oly[Aa]fter[Tt]ouch/{eow}      return(_POLYAFTERTOUCH);
  381.  
  382. <MIDI>[Aa]fter[Tt]ouch/{eow}      return(_AFTERTOUCH);
  383.  
  384. <MIDI>[Pp]itch[Bb]end/{eow}      return(_PITCHBEND);
  385.  
  386. <MIDI>[Gg][Mm][Rr]eset/{eow}      return(_GMRESET);
  387.  
  388. <MIDI>[Gg][Ss][Rr]eset/{eow}      return(_GSRESET);
  389.  
  390. <MIDI>[Gg][Ss][Ee]nter/{eow}      return(_GSRESET);
  391.  
  392. <MIDI>[Gg][Ss][Ee]xit/{eow}      return(_GSEXIT);
  393.  
  394. <MIDI>[Xx][Gg][Rr]eset/{eow}      return(_XGRESET);
  395.  
  396. <MIDI>"/*"              BEGIN CMNT;
  397. <MIDI>[A-Za-z_][A-Za-z0-9_]*      { char msg[128];
  398.                     sprintf(msg, "unknown keyword %s", yytext);
  399.                     yyerror(msg);
  400.                   }
  401. <MIDI>.                           { char msg[128];
  402.                     sprintf(msg, "invalid character %s", yytext);
  403.                     yyerror(msg);
  404.                   }
  405. <CMNT>"*/"                        BEGIN MIDI;
  406. <CMNT>.                 ;
  407. <CMNT>\n              src->linenr++;
  408.  
  409. <PROGRAM>[ \t]+             ;
  410. <PROGRAM>\n              src->linenr++;
  411. <PROGRAM>"$"{hexdigit}+   {
  412.               yylval.longv = strtol(strchr((char*)yytext, '$')+1, 0, 16);
  413.               BEGIN MIDI;
  414.               return(_NUMBER);
  415.                }
  416.  
  417. <PROGRAM>"0[xX]"{hexdigit}+   {
  418.             yylval.longv = strtol((char*)yytext+2, 0, 16);
  419.             BEGIN MIDI;
  420.             return(_NUMBER);
  421.               }
  422.  
  423. <PROGRAM>0[0-7]*/{eow}      {
  424.               yylval.longv = strtol(strchr((char*)yytext, '0'), 0, 8);
  425.               BEGIN MIDI;
  426.               return(_NUMBER);
  427.               }
  428.  
  429. <PROGRAM>[1-9][0-9]*/{eow}     {
  430.               yylval.longv = strtol((char*)yytext, 0, 10);
  431.               BEGIN MIDI;
  432.               return(_NUMBER);
  433.               }
  434.  
  435. <PROGRAM>[ABCD][1-8][1-8]/{eow} {
  436.             yylval.longv = ((yytext[0] - 'A') % 2) * 64 + (yytext[1] - '1') * 8 + (yytext[2]-'1');
  437.             BEGIN MIDI;
  438.             return(_NUMBER);
  439.               }
  440. <PROGRAM>[A-Za-z][A-Za-z0-9\.\-\!&]+/{eow}  {
  441.               int i, c;
  442.               char msg[128];
  443.  
  444.             for (i = 0; i < 128; i++)
  445.             for (c = 8; c <= 9; c++)
  446.               if (STRICMP((char*)yytext, progname(i, c)) == 0)
  447.               {
  448.                 BEGIN MIDI;
  449.                 yylval.longv = i;
  450.                 return(_NUMBER);
  451.               }
  452.  
  453.             sprintf(msg, "invalid program name %s", yytext);
  454.             yyerror(msg);
  455.               }
  456.  
  457. <PROGRAM>.        {
  458.     char msg[128];
  459.  
  460.       sprintf(msg, "invalid character %s", yytext);
  461.       yyerror(msg);
  462.     }
  463. %%
  464.  
  465. int noteval(char* notename)
  466. {
  467. int level = 0;
  468. char* s = notename;
  469.  
  470.   s[0] = toupper(s[0]);
  471.   switch(s[0])
  472.   {
  473.   case 'A': level = +9; break;
  474.   case 'B':
  475.   case 'H': level = +11; break;
  476.   case 'C': level = 0; break;
  477.   case 'D': level = 2; break;
  478.   case 'E': level = 4; break;
  479.   case 'F': level = 5; break;
  480.   case 'G': level = 7; break;
  481.   default: return -1;
  482.   }
  483.   s++;
  484.   if (*s =='#')
  485.   {
  486.     level++;
  487.     s++;
  488.   }
  489.   else if (strncmp(s, "is", 2) == 0)
  490.   {
  491.     level++;
  492.     s+=2;
  493.   }
  494.   else if (*s == 'b' || *s == 's')
  495.   {
  496.     level--;
  497.     s++;
  498.   }
  499.   else if (strncmp(s, "es", 2) == 0)
  500.   {
  501.     level--;
  502.     s+=2;
  503.   }
  504.   if (*s == '-' || (*s >= '0' && *s <= '9'))
  505.     level += 12 * (atoi(s)+1);
  506.   else
  507.     level += 12 * 5;  // default octave is C4..B4
  508.   if (level < 0 || level >= 128)
  509.   {
  510.   char msg[30];
  511.  
  512.     sprintf(msg, "note %s out of range C-1..C9", notename);
  513.     yyerror(msg);
  514.     level = 0;
  515.   }
  516.   return level;
  517. }
  518.  
  519. int newfile(char* name)
  520. {
  521. int i;
  522.  
  523.   // add to table
  524.   for (i = 0; i < filenames; i++)
  525.     if (STRICMP(name, filename[i]) == 0)
  526.       break;
  527.   if (i == filenames)
  528.   {
  529.     strcpy(filename[i], name);
  530.     filenames++;
  531.   }
  532.   src->index = i;
  533.   src->linenr = 1;
  534.   return i;
  535. }
  536.  
  537. void includefile(char* includename)
  538. {
  539. FILE* f = fopen(includename, "rt");
  540.  
  541.   if (!f)
  542.   {
  543.   char msg[128];
  544.  
  545.     sprintf(msg, "cannot open include file %s", includename);
  546.     yyerror(msg);
  547.   }
  548.   else
  549.   {
  550.   YY_BUFFER_STATE b;
  551.   lexstate* inc = (lexstate*)malloc(sizeof(lexstate));
  552.  
  553.     b = yy_create_buffer( f, 512 );
  554.  
  555.     assert(inc != 0);
  556.     init_lexstate(inc);
  557.  
  558.     inc->save = src;
  559.  
  560.     src->buffer = YY_CURRENT_BUFFER;
  561.     yy_switch_to_buffer(b);
  562.     inc->buffer = b;
  563.  
  564.     src = inc;
  565.  
  566.     printf("Including %s\n", includename);
  567.     src->index = newfile(includename);
  568.   }
  569. }
  570.  
  571. int yylex(void)
  572. {
  573. int t;
  574.  
  575. another:
  576.   t = ylex();
  577.  
  578.   if (t == 0 && src->save != 0)
  579.   {
  580.   lexstate* save;
  581.  
  582.     // end of include
  583.  
  584.     save = src->save;
  585.  
  586.     yy_delete_buffer(YY_CURRENT_BUFFER);
  587.     yy_switch_to_buffer(save->buffer);
  588.  
  589.     if (src) free(src);
  590.     src = save;
  591.     goto another;
  592.   }
  593.   return t;
  594. }
  595.  
  596. void lexstart(char* name)
  597. {
  598.   filenames = 0;
  599.   src = (lexstate*)malloc(sizeof(lexstate));
  600.   assert(src != 0);
  601.   init_lexstate (src);
  602.  
  603.   printf("Compiling %s\n", name);
  604.   src->index = newfile(name);
  605.   src->linenr = 1;
  606. }
  607.  
  608. long getlinenr()
  609. {
  610.   return src->linenr;
  611. }
  612.  
  613. int getsrcindex()
  614. {
  615.   return src->index;
  616. }
  617.  
  618. char* getsrcname( int index )
  619. {
  620.   if (index >= 0 && index < filenames)
  621.     return filename[index];
  622.   return 0;
  623. }
  624.  
  625. int srcfiles()
  626. {
  627.   return filenames;
  628. }
  629.